package bitetorrent.model;

import java.util.ArrayList;

/**
 *
 * @author user
 */
public class Pieces {

    public enum Status {
        NO, HAVE, INPROGRESS
    }
    
    public Status[] container;

    public Pieces(int length) {
        container = new Status[length];

        // Init
        for (int i = 0; i < length; ++i) {
            container[i] = Status.NO;
        }
    }

    public ArrayList<Integer> getAvailPieces() {
        ArrayList<Integer> avail = new ArrayList<Integer>();
        int i;
        int length = container.length;

        for (i = 0; i < length; ++i) {
            if (container[i] == Status.HAVE) {
                avail.add(i);
            }
        }

        return avail;
    }

    public byte[] getBitField() {
        int conLength = container.length;
        int bytelength = (int) Math.ceil(conLength / 8);
        byte[] bitField = new byte[bytelength];
        byte tmp = 0;
        int j = 0;

        for (int i = 0; i < conLength; ++i) {
            if (container[i] != Status.NO) {
                tmp |= 1 << (7 - (i % 8));
            }

            if (i != 0 && i % 8 == 0) {
                bitField[j++] = tmp;
                tmp = 0;
            }
        }

        return bitField;
    }

    public boolean isAvail(int index) {
        int length = container.length;

        // index terlalu besar
        if (index >= length) {
            return false;
        }

        return container[index] == Status.HAVE;
    }

    public void setAvail(int index) {
        if (index < container.length) {
            container[index] = Status.HAVE;
        }
    }

    public void setAvail(byte[] bitField) {
        int length =  bitField.length;
        for (int i=0; i< length; ++i) {
            byte number = bitField[i];
            for (int j=0; j < 8; ++j) {
                if (number >> (7 - j) == 1) {
                    setAvail(i * 8 + j);
                }
            }
        }
    }

    public void setAllAvail() {
        for (int i=0; i < container.length; ++i)  {
            setAvail(i);
        }
    }
}
